﻿using System;

namespace csharp___static_静态修饰符
{
    class Program
    {
        static void Main(string[] args)
        {
            var p1 = new Person("小A");
            var p2 = new Person("小B");
            var p3 = new Person("小C");
            var p4 = new Person("小V");
            Console.WriteLine($"我构造了四个人，他们是 {p1.name},{p2.name},{p3.name},{p4.name}");
            // 不能通过实例引用（p4）来访问静态成员
            //var size = p4.size;
            Console.WriteLine($"人类的骨骼数量 = {Person.size}");
        }
    }
    // static :静态的
    // 静态：静止的状态，石头，山。桌子，相对而言就叫 动态
    // static 修饰的字段 是专属于 类类型，不属于特定的对象（实例）。
    // static 用于修饰：类型本身、字段，方法、属性、事件，构造函数
    // static 不能用于： 索引器、析构函数
    // static 修饰的构造函数，不允许出现访问修饰符，就算你是 public 
    // static  修饰的构造函数无法调用
    // static 修饰的构造函数，必须无参数
    // static 修饰的常规方法、构造方法属性 中不能出现 实例对象的成员（this）,这些逻辑用来操作 静态的类类型成员
    // static 修饰的构造函数全局只执行一次，自动执行，并且执行的时机比常规构造函数要早。静态构造和常规构造可以共存
    // 在创建第一个实例或引用任何静态成员之前，将自动调用静态构造函数来初始化类。
    // 因为静态构造函数的优先级且唯一执行的特性用于加载配置很好用
    // Pinvoke 构造
    
    // 静态成员的生命周期是：从程序开始(被调用的那一刻起)到程序结束
    class Person
    {
        //人体的骨骼数量，static 表示它不属于特定对象的成员，它属于这个类类型
        public static int size = 206;
        public static  int Size { get; set; } //快捷键 prop = property： 属性 
        public static event Action OnEatAnything; //事件的写法
        //public delegate void ActionB();

        public string name;
        public  Person(string name)
        {
            Console.WriteLine("inside normal  function");
            this.name = name;
        }

        static Person() 
        {
            // 不能用实例引用（this）,来访问类类型的静态成员
            //this.size
            // 不能访问实例成员，但是可以访问静态成员
            // name = "";
            Console.WriteLine("inside static  function");
            size = 207;
        }

        /// <summary>
        /// 人类的吃东西的能力
        /// </summary>
        /// <param name="food">食物</param>
        public void Eat(string food)
        {
            Console.WriteLine($"{this.name} 吃了 {food}");
            // 非静态成员可以访问静态的成员，此处静态成员是 Function 方法
            Function();
        }

        public static void Function()
        {
            Console.WriteLine("inside person  static function");
            // this.Eat("");
        }

        /* static 对索引器无效，很好理解因为用到了 this 关键字，而this关键字是表示某一个对象实例
        string str;
        public static string this[int index] 
        {
            get => "11";
            set =>str=value;
        }
         */

        /* static 对析构函数无效
         ~static Person() 
        {
        }
 static ~ Person() 
{
}
 */
    }

    // static 修饰的class 中不能存在实例成员
    static class Dog
    {
        public static string name;
        public static void Eat() { }
    }
    // dog 无法派生出 dogg，因为 dog 为静态
    // static class Dogg : Dog { }
    // class Dogg : Dog { }

}
